<template>
  <view class="m-select-view">
    <view v-if="jumpSelection" @tap="toSelectPage">
      <slot v-bind="$attrs">
        <input :value="compData.label || modelValue" :disabled="true" :placeholder="placeholder"/>
        <view v-if="multiple && compData.labelOptions && compData.labelOptions.length" class="multiple-view">
          <view
            v-for="(option, index) in compData.labelOptions"
            :key="index"
            class="multiple-item-view gray-border"
            @tap.stop="del(option, index)"
          >
            <view class="multiple-info-view text-ellipsis-view">
              {{ option.label }}
            </view>
            <icons src="/static/icon/delete.svg" :props="{fill: `,,${$clr}`}" size="28"
                   style="position: absolute; top: -15rpx; right: -15rpx; z-index: 2;"/>
          </view>
        </view>
      </slot>
    </view>
    <picker v-else style="display: block; flex-grow: 1;" mode="selector" @change="change" :value="value"
            :range="options" :range-key="labelKey">
      <slot v-bind="$attrs">
        <input :value="compData.label || modelValue" :disabled="true" :placeholder="placeholder"/>
      </slot>
    </picker>
  </view>
</template>
<script setup>
import {computed, ref, watch} from 'vue'
import {cloneDeep} from 'lodash'
import {useDidShow} from '@tarojs/taro'

const props = defineProps({
  modelValue: {
    required: true,
    type: Array,
    default: () => []
  },
  options: {
    required: true,
    type: [Array, Object],
    default: () => []
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  jumpSelection: {
    type: Boolean,
    default: false,
  },
  valueKey: {
    type: String,
    default: () => ''
  },
  labelKey: {
    type: String,
    default: () => ''
  },
  placeholder: {
    type: String,
    default: () => ''
  },
})
const emit = defineEmits(['update:modelValue', 'tap', 'change', 'update:index'])
const show = ref(false)
const loading = ref(false)

const value = ref()// 索引值
const options = ref([]) // 选项
const valueKey = ref(props.valueKey)
const labelKey = ref(props.labelKey)
const jumpSelection = ref(props.jumpSelection) // 是否跳转到新页面选择


// watch(props, () => {
//   init()
//   // emit('change', compData.value)
// }, {deep: true})

watch(
  () => props.modelValue,
  () => {
    initValue()
    emit('change', compData.value)
  }
)

watch(
  () => props.options,
  () => init()
)

useDidShow(() => init())

// 初始化
function init() {
  jumpSelection.value = props.jumpSelection || props.multiple
  const copyOptions = cloneDeep(props.options)
  if (props.options instanceof Function || props.options instanceof Promise) {
    initPromiseData()
  } else {
    initConventionData(copyOptions)
  }
}

// 初始化promise的数据
function initPromiseData() {
  if (props.options instanceof Function) {
    const optionFun = props.options()
    if (optionFun instanceof Promise) {
      loading.value = true
      optionFun.then(opts => initConventionData(opts))
    } else {
      initConventionData(optionFun)
    }
  } else if (props.options instanceof Promise) {
    loading.value = true
    props.options.then(opts => initConventionData(opts))
  }
}


// 初始化常规数据
function initConventionData(data) {
  loading.value = false
  if (data instanceof Array) {
    valueKey.value = props.valueKey
    labelKey.value = props.labelKey
    initOptions(data)
  } else {
    valueKey.value = 'value'
    labelKey.value = 'label'
    const optArr = []
    for (const key in data) {
      optArr.push({
        value: key,
        label: data[key],
      })
    }
    initOptions(optArr)
  }
}

// 初始化options
function initOptions(rawOptions) {
  options.value = rawOptions
  initValue()
}

// 初始化value的值
function initValue() {
  if (props.modelValue || props.modelValue === 0) {
    if (props.multiple) {
      value.value = props.modelValue.map(value => {
        return options.value.findIndex(i => (valueKey.value ? i[valueKey.value] : i) === value)
      }).filter(i => i !== -1)
    } else {
      console.info('options.value', options.value)
      value.value = options.value.findIndex(i => (valueKey.value ? i[valueKey.value] : i) === props.modelValue)
    }
  } else {
    value.value = undefined
  }
}


const compData = computed(() => {
  return getCompData()
})

function getCompData() {
  if (!value.value && value.value !== 0) return {}
  let modelValue, label, labelOptions, selectOptions
  if (props.multiple) {
    modelValue = value.value.map(i => {
      return valueKey.value ? options.value[i][valueKey.value] : options.value[i]
    })
    // if (props.modelValue instanceof Array) {
    //   if (modelValue.every((a, i) => a === props.modelValue[i])) {
    //     modelValue = props.modelValue
    //   }
    // }
    label = (value.value.length || '') && `已选择${value.value.length}个`
    labelOptions = value.value.map(index => {
      return {
        index,
        label: labelKey.value ? options.value[index][labelKey.value] : options.value[index]
      }
    })
    selectOptions = value.value.map(index => options.value[index])
  } else {
    modelValue = valueKey.value ? options.value[value.value][valueKey.value] : options.value[value.value]
    // if (modelValue === props.modelValue) modelValue = props.modelValue
    label = labelKey.value ? options.value[value.value][labelKey.value] : options.value[value.value]
    selectOptions = options.value[value.value]
  }
  return {
    modelValue,
    label,
    labelOptions,
    selectOptions,
    selectIndex: value.value
  }
}

function tap() {
  show.value = true
}

function change(e) {
  value.value = e.detail.value
  toEmit()
}

function close() {
  show.value = false
}

function confirm(e) {
  close()
  value.value = e.detail
  toEmit()
}

function toEmit() {
  const data = getCompData()
  emit('update:modelValue', data.modelValue)
  emit('change', data)
}


function toSelectPage() {
  initPromiseData()
  let pages = getCurrentPages()
  let currPage = pages[pages.length - 1]
  currPage.data.pageHandler = {
    multiple: props.multiple,
    options: options,
    labelKey: labelKey.value,
    value: value.value,
    loading: loading,
    submit: submit,
  }
  wx.navigateTo({
    url: '/pages/common/select'
  })
}

function submit(val) {
  let pages = getCurrentPages()
  let currPage = pages[pages.length - 1]
  delete currPage.data.pageHandler
  value.value = val
  toEmit()
}

function del(option, index) {
  value.value.splice(index, 1)
  toEmit()
}
</script>
<style lang="scss">
.m-select-view {
  background-color: white;
  display: flex;
  flex-grow: 1;

  .picker-slot-view {
    flex-grow: 1;
  }

  > view {
    flex-grow: 1;
  }

  .multiple-view {
    background-color: white;
    display: flex;
    flex-wrap: wrap;
    padding-top: 0.5em;

    .multiple-item-view {
      height: 2em;
      display: flex;
      position: relative;
      border-radius: 8rpx;
      margin: 7rpx;

      .multiple-info-view {
        padding: 0 20rpx;
        text-align: center;
        line-height: 2em;
      }
    }
  }
}
</style>
